/*******************************************************************************
 * Copyright (c) 2007 TOPCASED. All rights reserved. This program
 * and the accompanying materials are made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: Topcased contributors and others - initial API and implementation
 *******************************************************************************/
/**
 * This is a fork of the UML2Java Plug-in developed by Topcased and released under
 * the Eclipse EPL License. http://www.eclipse.org/legal/epl-v10.html
 * In accordance with the license, I have forked the UML2Java plugin and have adapted
 * it to suit the needs of a UML2QoS instrumentation code generator for PHP.
 * 
 * @author Alexandru Burdusel
 */
package org.topcased.uml2qos.services;

import java.util.Hashtable;

import org.topcased.uml2qos.GenQosOperation;
import org.topcased.uml2qos.utilities.Log;

/**
 * PHP Services : methods for manipulating specific Ecore and PHP features
 * 
 * @author Ariel RAMPHUL (Sopra Group - Toulouse)
 * @author Pascal GARCIA (Sopra Group - Toulouse)
 */
public class PhpServices
{

	private static class simpleClassifierItem
	{
		String name;
		String packageName;
		int launchID;
		
		public simpleClassifierItem(String n, String pN)
		{
			name = n;
			packageName = pN;
			launchID = GenQosOperation.getLaunchID();
		}
		
	}
	
    private static Hashtable<String, simpleClassifierItem> classifierList = new Hashtable<String, simpleClassifierItem>();

    /**
     * Get the php type corresponding to the Ecore primitive type
     * 
     * @param stDiagramType the ecore primitive type
     * @return the corresponding php type
     */
    public static String stGetPhpType(String stDiagramType)
    {
        String stRetVal;
        if (stDiagramType.equalsIgnoreCase("EString"))
        {
            stRetVal = "String";
        }
        else if (stDiagramType.equalsIgnoreCase("EInt"))
        {
            stRetVal = "int";
        }
        else if (stDiagramType.equalsIgnoreCase("EBoolean"))
        {
            stRetVal = "boolean";
        }
        else if (stDiagramType.equalsIgnoreCase("EFloat"))
        {
            stRetVal = "float";
        }
        else
        {
            stRetVal = stDiagramType;
        }
        return stRetVal;
    }
    
    /**
     * Get the default initialisation value for Ecore primitive type or Java type
     * 
     * @param stDiagramType the ecore primitive type or java type
     * @return the default initialisation value, as a String
     */
    public static String stGetPhpDefaultValForType(String stDiagramType)

    {
        String stRetVal;

        // Ecore primitive type
        if (stDiagramType.equalsIgnoreCase("EString"))
        {
        	stRetVal = "''";
        }
        else if (stDiagramType.equalsIgnoreCase("EInt"))
        {
            stRetVal = "0";
        }
        else if (stDiagramType.equalsIgnoreCase("EBoolean"))
        {
            stRetVal = "false";
        }
        else if (stDiagramType.equalsIgnoreCase("EFloat"))
        {
            stRetVal = "0.0";
        }
        else if (stDiagramType.equalsIgnoreCase("EByte"))
        {
        	stRetVal = "''";
        }
        else if (stDiagramType.equalsIgnoreCase("EShort"))
        {
        	stRetVal = "''";
        }
        else if (stDiagramType.equalsIgnoreCase("ELong"))
        {
        	stRetVal = "''";
        }
        else if (stDiagramType.equalsIgnoreCase("EDouble"))
        {
            stRetVal = "''";
        }

        // PHP primitive type
        else if (stDiagramType.equalsIgnoreCase("String"))
        {
        	stRetVal = "''";
        }
        else if (stDiagramType.equalsIgnoreCase("Int"))
        {
            stRetVal = "0";
        }
        else if (stDiagramType.equalsIgnoreCase("Boolean"))
        {
            stRetVal = "false";
        }
        else if (stDiagramType.equalsIgnoreCase("Float"))
        {
            stRetVal = "0.0";
        } else if (stDiagramType.equalsIgnoreCase(""))
        {
        	stRetVal = "''";
    	}	
        else
        {
            stRetVal = "new " + stDiagramType + "()";
        }
        
        return stRetVal;
    }

    /**
     * Return the string " static " if the parameter is true
     * 
     * @param isStatic : boolean
     * @return the string " static " if the parameter is true
     */
    public static String stIsStaticToString(boolean isStatic)
    {
        if (isStatic)
        {
            return " static";
        }
        return "";
    }

    /**
     * Return the string " final " if the parameter is true
     * 
     * @param isReadOnly : boolean
     * @return the string " final " if the parameter is true
     */
    public static String stIsReadOnlyToString(boolean isReadOnly)
    {
        if (isReadOnly)
        {
            return " final";
        }
        return "";
    }

    /**
     * Return the string " abstract " if the parameter is true
     * 
     * @param isAbstract : boolean
     * @return the string " abstract " if the parameter is true
     */
    public static String stIsAbstractToString(boolean isAbstract)
    {
        if (isAbstract)
        {
            return " abstract ";
        }
        return "";
    }

    public static boolean isClass(org.eclipse.uml2.uml.Class c)
    {
        return !(c instanceof org.eclipse.uml2.uml.OpaqueBehavior);
    }

    public static void checkInheritance(org.eclipse.uml2.uml.Class c)
    {
        if (c.getSuperClasses() != null)
        {
            if (c.getSuperClasses().size() > 1)
            {
                Log.log("[05] The class named <" + c.getName() + "> has two or more superclasses. PHP doesn't support multiple inheritances.");
            }
        }
    }

    public static void checkDuplicateClassifier(org.eclipse.uml2.uml.Class c)
    {
    	
    	org.eclipse.uml2.uml.Package p = (org.eclipse.uml2.uml.Package) c.getOwner();
    	String n = p.getName();
    	simpleClassifierItem sAI = new simpleClassifierItem(c.getName(),n);
    	
        if (!(c instanceof org.eclipse.uml2.uml.OpaqueBehavior))
        {
            if (classifierList.containsKey(sAI.packageName + "*" + sAI.name) && (classifierList.get(sAI.packageName + "*" + sAI.name).launchID == GenQosOperation.getLaunchID()))
            {
                Log.log("[06] Two or more classifiers have the same name <" + c.getName() + "> in the package <" + sAI.packageName + ">. Generated code may contains errors");
                classifierList.put(sAI.packageName + "*" + sAI.name, sAI);
            }
            else
            {
            	classifierList.put(sAI.packageName + "*" + sAI.name, sAI);
            }
        }
    }

    public static void checkDuplicateClassifier(org.eclipse.uml2.uml.Interface c)
    {
    	org.eclipse.uml2.uml.Package p = (org.eclipse.uml2.uml.Package) c.getOwner();
    	String n = p.getName();
    	simpleClassifierItem sAI = new simpleClassifierItem(c.getName(),n);

        if (classifierList.containsKey(sAI.packageName + "*" + sAI.name) && (classifierList.get(sAI.packageName + "*" + sAI.name).launchID == GenQosOperation.getLaunchID()))
        {
        	Log.log("[06] Two or more classifiers have the same name <" + c.getName() + "> in the package <" + sAI.packageName + ">. Generated code may contains errors");
            classifierList.put(sAI.packageName + "*" + sAI.name, sAI);
        }
        else
        {
        	classifierList.put(sAI.packageName + "*" + sAI.name, sAI);
        }
    }

    public static void checkDuplicateClassifier(org.eclipse.uml2.uml.Enumeration c)
    {
    	org.eclipse.uml2.uml.Package p = (org.eclipse.uml2.uml.Package) c.getOwner();
    	String n = p.getName();
    	simpleClassifierItem sAI = new simpleClassifierItem(c.getName(),n);

        if (classifierList.containsKey(sAI.packageName + "*" + sAI.name) && (classifierList.get(sAI.packageName + "*" + sAI.name).launchID == GenQosOperation.getLaunchID()))
        {
        	Log.log("[06] Two or more classifiers have the same name <" + c.getName() + "> in the package <" + sAI.packageName + ">. Generated code may contains errors");
            classifierList.put(sAI.packageName + "*" + sAI.name, sAI);
        }
        else
        {
        	classifierList.put(sAI.packageName + "*" + sAI.name, sAI);
        }
    }
    
    public static String getArrayType(){
    	return "Array Type";
    }

}
